package org.linlinjava.litemall.wx.service;

import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.SneakyThrows;
import org.linlinjava.litemall.core.payment.clover.rs.ApiCustomerRS;
import org.linlinjava.litemall.core.payment.clover.service.impl.GoodsCloverServiceImpl;
import org.linlinjava.litemall.core.util.RegexUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.service.*;
import org.linlinjava.litemall.wx.dto.IdCardDTO;
import org.linlinjava.litemall.wx.vo.AddressVo;
import org.linlinjava.litemall.wx.vo.IdCardVo;
import org.linlinjava.litemall.core.payment.clover.vo.CardInfoReqVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.regex.Pattern;

import static org.linlinjava.litemall.wx.util.WxResponseCode.*;

@Service
public class IdCardService {
    @Autowired
    private LumiereIdCardService idCardService;

    @Autowired
    private LitemallAddressService addressService;

    @Autowired
    private WxCloverPayService wxCloverPayService;

    @Autowired
    private LitemallRegionService regionService;

    @Autowired
    private LumiereCloverCardService lumiereCloverCardService;

    @Autowired
    private LumiereCloverCardInfoService lumiereCloverCardInfoService;

    @Autowired
    private GoodsCloverServiceImpl cloverService;


    /**
     * 获取code 申请 acces_token保存
     * @param merchantId
     * @param employeeId
     * @param clientId
     * @param code
     * @return
     */
    public Object acquireCode(String merchantId, String employeeId, String clientId, String code) {
        return cloverService.acquireCode(merchantId,employeeId,clientId,code);
    }

    @Transactional
    public Object createCloverCard(Integer userId, CardInfoReqVO cardInfo) {
        //判断是否是新顾客
        LumiereCloverCard cc = lumiereCloverCardService.findByUserId(userId);

        List<LumiereCloverCardInfo> list = lumiereCloverCardInfoService.list(Wrappers.lambdaQuery(LumiereCloverCardInfo.class)
                .eq(LumiereCloverCardInfo::getUserId,userId)
                .eq(LumiereCloverCardInfo::getFirst6,cardInfo.getFirst6())
                .eq(LumiereCloverCardInfo::getLast4, cardInfo.getLast4()));
        if(CollUtil.isNotEmpty(list)){return ResponseUtil.ok();}
        return cloverService.createCustomer(userId,cardInfo,cc);
    }

    @Transactional
    public Object createCloverCard(Integer userId, String token) {

        //判断是否是新顾客
        LumiereCloverCard cc = lumiereCloverCardService.findByUserId(userId);
        return ObjectUtil.isNotNull(cc)?cloverService.appendCustomer(userId,token,cc.getCustomerId()):
                cloverService.createCustomer(userId,token);
    }


    @SneakyThrows
    public List<ApiCustomerRS> cardList(Integer userId) {
        LumiereCloverCard cloverCard = lumiereCloverCardService.findByUserId(userId);
        if(ObjectUtil.isNull(cloverCard)){return CollUtil.newArrayList();}
        return cloverService.getCustomerCards(cloverCard.getCustomerId());
    }

    public List<ApiCustomerRS> cardInfoByUserIdList(Integer userId) {
        List<LumiereCloverCardInfo> list = lumiereCloverCardInfoService.list(Wrappers.lambdaQuery(LumiereCloverCardInfo.class).eq(LumiereCloverCardInfo::getUserId, userId));
        LumiereCloverCard byUserId = lumiereCloverCardService.findByUserId(userId);
        return CollStreamUtil.toList(list,cardInfo->new ApiCustomerRS()
                .setId(cardInfo.getCardId())
                .setFirst6(cardInfo.getFirst6())
                .setLast4(cardInfo.getLast4())
                .setCardType(cardInfo.getBrand())
                .setMonth(cardInfo.getExpMonth())
                .setYear(cardInfo.getExpYear())
                .setToken(byUserId.getCustomerId()));
    }

    @Transactional
    public Object deleteCard(Integer userId, String cardId) {
        LumiereCloverCard cc = lumiereCloverCardService.findByUserId(userId);
        if(ObjectUtil.isNull(cc)){return ResponseUtil.fail(DELETE_CARD_ERROR, "删除失败");}
        Object result = cloverService.deleteCustomer(cc.getCustomerId(), cardId);
        //删除数据
        LumiereCloverCardInfo cloverCardInfo = lumiereCloverCardInfoService.getOne(Wrappers.lambdaQuery(LumiereCloverCardInfo.class)
                .eq(LumiereCloverCardInfo::getCardId,cardId));
        if(cloverCardInfo!=null){
            lumiereCloverCardInfoService.removeById(cloverCardInfo);
        }
        return ResponseUtil.ok();
    }




    @Transactional(rollbackFor = Exception.class)
    public Object createCard(Integer userId, IdCardDTO dto, AddressVo address) throws Exception {

        //校验信用卡卡号
        String cardNo = dto.getCardNo();
        if (cardNo.length() < 13 || cardNo.length() > 19) {
            return ResponseUtil.fail(INVALID_ID_CARD, "错误的信用卡");
        } else {
            Pattern pattern = Pattern.compile("^-?\\d+(\\.\\d+)?$");
            if (!pattern.matcher(cardNo).matches()) {
                return ResponseUtil.fail(INVALID_CARDNO, "错误的信用卡卡号");
            }
        }

        //查看信用卡是否已经被绑定
        List<LumiereIdcard> cards = idCardService.findByUserIdAndCardNo(userId, cardNo);
        if (cards.size() > 0) {
            return ResponseUtil.fail(EXIST_ID_CARD, "用户已绑定该信用卡");
        }

        String[] dates = dto.getExpiredMonth().split("/");
        for (int i = 0; i < dates.length; i++) {
            if (dates[i].startsWith("0")) {
                dates[i] = dates[i].replace("0", "");
            }
        }

//        判断信用卡信息是否正确
//        boolean flag = wxCloverPayService.beforeCreate(dto.getCardNo(), userId);

//        if (!flag) {
//            return ResponseUtil.fail(INVALID_ID_CARD, "信用卡信息错误");
//        }

        //拼接地址信息
        LitemallAddress addr = new LitemallAddress();
        BeanUtils.copyProperties(address, addr);
//        addr.setName(address.getSurname()+address.getName());

        //如果地址id不为空，则地址已存在
        Object error = validate(addr);
        if (error != null) {
            return error;
        }

        addr.setId(null);
        addr.setUserId(userId);
        addressService.add(addr);

        LumiereIdcard idcard = new LumiereIdcard();
        BeanUtils.copyProperties(dto, idcard);


        idcard.setExpiredYear(Short.valueOf(dates[1]));
        idcard.setExpiredMonth(Short.valueOf(dates[0]));
        idcard.setUserId(userId);
        idcard.setAddressId(addr.getId());
        idcard.setAddTime(LocalDateTime.now());
        idcard.setUpdateTime(LocalDateTime.now());
        idcard.setDeleted(false);
        idCardService.add(idcard);
        return ResponseUtil.ok("添加成功");
    }

    public Object detail(Integer userId, Integer cardId) {
        LumiereIdcard idcard = idCardService.findById(cardId);

        if (idcard == null || idcard.getDeleted() || !idcard.getUserId().equals(userId)) {
            return ResponseUtil.fail(INVALID_ID_CARD, "错误的信用卡");
        }

        LitemallAddress address = addressService.findById(idcard.getAddressId());

        IdCardVo vo = new IdCardVo();
        BeanUtils.copyProperties(idcard, vo);
        BeanUtils.copyProperties(address, vo);

        List<LitemallRegion> regions = regionService.queryByPid(0);

        regions.stream().forEach(region -> {
            if (region.getCode().equals(address.getCountry())) {
                vo.setCountryNameCn(region.getNameCn());
                vo.setCountryNameEn(region.getNameEn());
            }
        });

        if (idcard.getExpiredMonth() < 10) {

            vo.setExpiredMonth("0" + idcard.getExpiredMonth() + "/" + idcard.getExpiredYear());
        } else {
            vo.setExpiredMonth(idcard.getExpiredMonth() + "/" + idcard.getExpiredYear());
        }
        vo.setAddressId(idcard.getAddressId());
        return ResponseUtil.ok(vo);
    }

    public Object list(Integer userId) {
        List<LumiereIdcard> list = idCardService.findByUserId(userId);
        return ResponseUtil.okList(list);
    }


    public Object delete(Integer cardId) {
        LumiereIdcard idcard = idCardService.findById(cardId);

        if (idcard == null) {
            return ResponseUtil.fail(INVALID_ID_CARD, "不存在的信用卡");
        }
        idCardService.delete(cardId);

        return ResponseUtil.ok("删除信用卡成功");
    }

    private Object validate(LitemallAddress address) {
        String name = address.getName();
        if (StringUtils.isEmpty(name)) {
            return ResponseUtil.badArgument(NAME_NULL, "param: name is null");
        }

        String surname = address.getSurname();

        if (StringUtils.isEmpty(surname)) {
            return ResponseUtil.badArgument(SURNAME_NULL, "param: surname is null");
        }


        // 测试收货手机号码是否正确
        String mobile = address.getTel();

        if (!StringUtils.isEmpty(mobile) && !RegexUtil.isMobileExact(mobile)) {
            return ResponseUtil.badArgument(MOBILE_FORMARTTER_ERROR, "param: mobile fomartter is error");
        }

        String province = address.getProvince();
        if (StringUtils.isEmpty(province)) {
            return ResponseUtil.badArgument(PROVINCE_NULL, "param: province is null");
        }

        String city = address.getCity();
        if (StringUtils.isEmpty(city)) {
            return ResponseUtil.badArgument(CITY_NULL, "param: city is null");
        }


        String country = address.getCountry();
        if (StringUtils.isEmpty(country)) {
            return ResponseUtil.badArgument(COUNTRY_NULL, "param: country is null");
        }

        String detailedAddress = address.getAddressDetail();
        if (StringUtils.isEmpty(detailedAddress)) {
            return ResponseUtil.badArgument(DETAILADDRESS_NULL, "param: detailedAddress is null");
        }

        return null;
    }






}
